<HTML>
<HEAD>
    <title>Tetris</title>
    <script>
        window.resizeTo(410, 450)

        function unSel() {
            document.execCommand("Unselect");
            window.setTimeout("unSel()", 100);
        }

        unSel();
    </script>
    <style>
        .MB {
            BACKGROUND-COLOR: firebrick;
            CURSOR: default;
            HEIGHT: 22px;
            WIDTH: 22px
        }

        .SB {
            BACKGROUND-COLOR: slategray;
            CURSOR: default;
            HEIGHT: 22px;
            WIDTH: 22px
        }

        .BK {
            BACKGROUND-COLOR: white;
            CURSOR: default;
            HEIGHT: 22px;
            WIDTH: 22px
        }

        .GT {
            BORDER-BOTTOM: deepskyblue thin solid;
            BORDER-LEFT: deepskyblue thin solid;
            BORDER-RIGHT: deepskyblue thin solid;
            BORDER-TOP: deepskyblue thin solid;
            CURSOR: default
        }
    </style>
</HEAD>

<BODY bgcolor="#EAF0F8" onkeydown="return keyControl();" topmargin="10" leftmargin="10" rightmargin="10"
      bottommargin="0" scroll=no>
<div id="BoardRaw" style="display: none">
    <table cellspacing=2 cellpadding=0 class=gt border=0 bordercolor="#EAF0F8" bgcolor="#EAF0F8" style="float: left;">
        <tr>
            <td valign="top">
                <table cellspacing=0 cellpadding=0 class=gt border=1 bordercolor="#EAF0F8" style="">
                    <Tbody class="board">
                    <tr>
                        <td nowrap class=BK></td>
                        <td nowrap class=BK></td>
                        <td nowrap class=BK></td>
                        <td nowrap class=BK></td>
                        <td nowrap class=BK></td>
                        <td nowrap class=BK>
                        </td>
                        <td nowrap class=BK></td>
                        <td nowrap class=BK></td>
                        <td nowrap class=BK></td>
                        <td nowrap class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK>
                        </td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK>
                        </td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK>
                        </td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK>
                        </td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK>
                        </td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    <tr>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                        <td class=BK></td>
                    </tr>
                    </tbody>
                </table>
            </td>
        </tr>
        <tr>
            <td class="user_name">对手id：</td>
        </tr>
        <tr>
            <td class="user_score">对手分数：0</td>
        </tr>
    </table>
</div>

<table border="0" width="100%" cellspacing="0" cellpadding="0" height="100%">
    <tr id="competitor_area">

    </tr>
    <tr>
        <td width="100%" height="100%" align="center">
            <table cellspacing=2 cellpadding=0 class=gt border=0 bordercolor="#EAF0F8" bgcolor="#EAF0F8">
                <tr>
                    <td valign="top">
                        <table cellspacing=0 cellpadding=0 class=gt border=1 bordercolor="#EAF0F8" style="">
                            <Tbody id=GameBar>
                            <tr>
                                <td nowrap class=BK></td>
                                <td nowrap class=BK></td>
                                <td nowrap class=BK></td>
                                <td nowrap class=BK></td>
                                <td nowrap class=BK></td>
                                <td nowrap class=BK></td>
                                <td nowrap class=BK></td>
                                <td nowrap class=BK></td>
                                <td nowrap class=BK></td>
                                <td nowrap class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK>
                                </td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK>
                                </td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            </tbody>
                        </table>
                    </td>
                    <td valign="top" align="center" style="padding: 10 10 0 10" bgcolor="#466285">
                        <table cellspacing=0 cellpadding=0 border=0>
                            <tr>
                                <td><font size=5 color=red face=consolas>Tetris</font></td>
                            </tr>
                        </table>
                        <table id="previewWnd" cellspacing=0 cellpadding=0 class=gt border=1 bordercolor="#EAF0F8"
                               bgcolor="#EAF0F8" style="margin-top:15">
                            <Tbody id="previewBar">
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            <tr>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                                <td class=BK></td>
                            </tr>
                            </tbody>
                        </table>
                        <table cellspacing=3 cellpadding=0 border=0 style="margin-top:15">
                            <tr>
                                <td><input type=button id="CreateRoom"
                                           style="font-family:Tahoma; font-size:9pt; width:100px" value="CreateRoom"
                                           onclick="CreateRoom();"></td>
                            </tr>
                            <tr>
                                <td><input type=button id="start_game"
                                           style="font-family:Tahoma; font-size:9pt; width:100px" value="start_game"
                                           onclick="start_game();"></td>
                            </tr>
                        </table>
                        <table cellspacing=3 cellpadding=0 border=0
                               style="font-family:Tahoma; font-size:9pt; font-weight: bold; margin-top:10">
                            <tr>
                                <td id=scoreBar style="color:#FFFFFF">Score : 0</td>
                            </tr>
                            <tr>
                                <td id=speedBar style="color:#FFFFFF">Speed : 1</td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>
</BODY>
</HTML>
<script>
    // 在这里定义全局的变量
    // 游戏状态，0表示没开始游戏，1表示正在游戏
    var GAME_STATUS = 0;

    // 用户的游戏状态 0-未开始,1-正在游戏,2-已结束
    var USER_GAME_STATUS;

    // 房间id string
    var ROOM_ID = "";

    // 当前用户的token
    var TOKEN = "";

    // webSocket连接
    var WS;

    // 当前房间的房主
    var ROOM_OWNER;

    // 房间人数
    var ROOM_USER_COUNT = 0;

    // 游戏超时时间 单位毫秒 timeout 为0 游戏结束
    var GAME_TIMEOUT;
    // 游戏的结束时间 单位毫秒
    var GAME_END_TIME;

    // 游戏随机数
    var GAME_RANDOM = [];

    // 当前下标
    var GAME_INDEX = 0;

</script>

<script>
    // 对战模式的逻辑代码
    // 进入就先直接登录
    login();

    // 登录
    function login() {
        // 后端服务会生成一个uuid作为前端的标识，并且会写入到cookie中
        // 请求其他接口时，应该携带这个uuid
        const url = getDomain() + '/api/login';
        const data = {};

        fetch(url, {
            method: 'POST',
            headers: {},
            body: JSON.stringify(data)
        })
            .then(response => response.json())
            .then(data => {
                if (data.code != 1) {
                    alert("登录失败")
                }
                // 保存token
                TOKEN = data.data.token;
                // 只要登录成功，就开始连接ws
                conn_ws();

                GAME_INDEX = data.data.index ?? 0;
                score = data.data.score ?? 0;
                ROOM_ID = data.data.room_id ?? "";
                USER_GAME_STATUS = data.data.game_status ?? 0;

                // 表示正在游戏中
                if (data.data.board) {
                    // 如果是正在游戏中，调用了Login，则证明用户刷新了页面。则index需要-1
                    // 因为原本在预览区的方块，还没有得到显示，就被刷新页面了
                    GAME_INDEX -= 1;
                    setSelfBoard(data.data.board)
                }

                if (ROOM_ID !== "") {
                    getRoomInfo()
                }

                // 进入房间中
                goRoom();
            })
            .catch(error => {
                console.error('Error:', error);
            });


    }

    // 设置自己的棋盘
    function setSelfBoard(board) {
        for (var i = 0; i < board.length; i++) {
            for (var j = 0; j < board[i].length; j++) {
                setClass(j, i, board[i][j])
            }
        }
    }


    // 连接ws
    function conn_ws() {
        var address = "ws:" + getDomain() + "/ws?token=" + TOKEN
        WS = new WebSocket(address);

        // 连接建立时的回调函数
        WS.onopen = function (event) {
            console.log("WebSocket连接已建立");
        };

        // 接收到消息时的回调函数
        WS.onmessage = function (event) {
            var message = event.data;
            // 将Message解析为json
            var json = JSON.parse(message);
            // console.log("接收到消息：" + message);
            // console.log(json);
            if (json.command == 'start_game') {
                GAME_RANDOM = json.data.randArr;
                GAME_INDEX = 0;
                GAME_TIMEOUT = json.data.timeout;
                // 游戏结束时间
                GAME_END_TIME = new Date().getTime() + GAME_TIMEOUT;
                // 游戏状态,开始游戏
                GAME_STATUS = 1;
                USER_GAME_STATUS = 1;
                setGameStatus(1)
                beginGameClear();
                beginGame();
            }
            if (json.command == 'join_room') {
                // 加入房间
                console.log(json.data.token + "加入房间")
                // 重新加载房间数据
                getRoomInfo();
            }


            // 同步玩家状态
            if (json.command == 'sync_game_status') {
                // 游戏同步
                GAME_TIMEOUT = json.data.timeout;
                // GAME_STATUS = json.data.game_status;

                // 循环 user_list
                for (var i = 0; i < json.data.user_list.length; i++) {
                    setCompetitorData(json.data.user_list[i])
                }
            }

            if (json.command == "game_over") {
                console.log(json.data)
                var maxScore = 0;
                var maxToken = "";
                // 循环对象
                for (var key in json.data) {
                    if(json.data[key] >= maxScore){
                        maxScore = json.data[key];
                        maxToken = key;
                    }
                }

                if(maxScore > 0){
                    alert("游戏结束，获胜者是：" + maxToken + "，分数为：" + maxScore)
                }
                // 游戏结束
                GAME_STATUS = 0;
                USER_GAME_STATUS = 0;
                score = 0;
                GAME_INDEX = 0;
                GAME_TIMEOUT = 0;
                GAME_END_TIME = 0;
                GAME_RANDOM = [];
                // 清空棋盘
                clearBoard();
                setGameStatus(0)
            }
        };

        // 连接关闭时的回调函数
        WS.onclose = function (event) {
            console.log("WebSocket连接已关闭");
            WS = null;
        };

        // 发送消息
        function sendMessage(message) {
            // ToDo 为了保持链接，可以定时发送ping
            WS.send(message);
        }

        // 关闭连接
        function closeConnection() {
            WS.close();
        }

    }

    function clearBoard() {
        // 游戏区
        for (var i = 0; i < 16; i++) {
            for (var j = 0; j < 10; j++) {
                setClass(j, i, "BK")
            }
        }
        BX = BY =  new Array(4)

        // 预览区
        // 预览区空白
        for (i = 0; i < 4; i++) {
            for (j = 0; j < 4; j++) {
                previewBar.children[j].children[i].className = "BK";
            }
        }
        PX = PY = new Array(4)

        getRoomInfo();
    }

    // 设置游戏状态
    function setGameStatus(game_status) {
        USER_GAME_STATUS = game_status;

        switch (USER_GAME_STATUS) {
            case 0:
                if (ROOM_ID) {
                    // 隐藏创建房间按钮
                    document.getElementById("CreateRoom").style.display = "none";
                }

                // 未开始状态，可以显示开始游戏按钮
                document.getElementById("start_game").style.display = "block"

                // 如果当前用户不是房主，则隐藏开始游戏按钮
                if (ROOM_ID && ROOM_OWNER !== TOKEN) {
                    // 表示游戏未开始，可以显示开始游戏按钮
                    document.getElementById("start_game").style.display = "none"
                }


                break;

            case 1: // 正在游戏中
            case 2:
                document.getElementById("CreateRoom").style.display = "none";
                document.getElementById("start_game").style.display = "none"
                break;

        }


    }


    // 设置对手的游戏棋盘
    function setCompetitorBar(userToken, board) {
        var new_id = "competitor_area_" + userToken;

        var area_td = document.getElementById(new_id);

        // 找到area_td里面的class=board
        var tbody = area_td.getElementsByClassName("board")[0];

        // 循环board
        for (var i = 0; i < board.length; i++) {
            var bar = board[i];
            // 循环bar
            for (var j = 0; j < bar.length; j++) {
                setClass2(tbody, j, i, bar[j])
            }
        }

    }

    // 设置对手的游戏棋盘
    function setCompetitorData(data) {
        var userToken = data.token;
        var userScore = data.score;
        var userBoard = data.board || [];

        if (userToken === TOKEN) {
            return;
        }

        var new_id = "competitor_area_" + userToken;

        var area_td = document.getElementById(new_id);

        // 如果没有找到，则创建
        if (area_td == null) {
            buildCompetitorBar(userToken)
            area_td = document.getElementById(new_id);
        }

        // 找到area_td里面的class=board
        var tbody = area_td.getElementsByClassName("board")[0];

        // 循环board
        for (var i = 0; i < userBoard.length; i++) {
            var bar = userBoard[i];
            // 循环bar
            for (var j = 0; j < bar.length; j++) {
                setClass2(tbody, j, i, bar[j])
            }
        }

        // 设置分数
        var score = area_td.getElementsByClassName("user_score")[0];
        score.innerHTML = "对手分数：" + userScore;
    }

    function reBuildCompetitorBar(user_list) {
        var competitor_area = document.getElementById("competitor_area");
        competitor_area.innerHTML = "";

        ROOM_USER_COUNT = user_list.length;
        for (var i = 0; i < user_list.length; i++) {
            var user = user_list[i];
            if (user.token == TOKEN) {
                continue;
            }

            buildCompetitorBar(user.token)
            setCompetitorData(user_list[i])
        }
    }

    // 构建对手的游戏棋盘
    function buildCompetitorBar(user_id) {
        // 复制BoardRaw的内容添加到competitor_area中
        var BoardRaw = document.getElementById("BoardRaw");

        var competitor_area = document.getElementById("competitor_area");

        // 创建一个td
        var td = document.createElement("td");

        var new_id = "competitor_area_" + user_id;
        td.setAttribute("id", new_id);
        td.setAttribute("style", "width: 100%;");

        // 复制BoardRaw的内容添加到td中
        td.innerHTML = BoardRaw.innerHTML;

        // 将td加入到competitor_area中
        competitor_area.appendChild(td);

        // 设置对手的名字
        var competitor_name = document.getElementById(new_id);
        competitor_name.getElementsByClassName("user_name")[0].innerHTML = "对手ID:" + user_id;
    }

    // 获取domain
    function getDomain() {
        return "//" + document.domain;
    }

    // 创建房间
    function CreateRoom() {
        // 判断当前状态，是否可以创建房间
        if (TOKEN === "" || WS == null) {
            alert("当前状态不允许创建房间");
            return;
        }

        const url = getDomain() + '/api/create_room';
        const data = {
            token: TOKEN
        };

        fetch(url, {
            method: 'POST',
            headers: {},
            body: JSON.stringify(data)
        })
            .then(response => response.json())
            .then(data => {
                if (data.code != 0) {
                    alert("创建房间成功")
                    // 房间号
                    ROOM_ID = data.data.room_id;

                    // 表示只有自己
                    ROOM_USER_COUNT = 1;
                    // 邀请链接
                    console.log("http:" + getDomain() + "/web/battle.html?room_id=" + ROOM_ID)

                    // 如果成功创建房间，则隐藏创建房间的按钮
                    document.getElementById("CreateRoom").style.display = "none";
                }
            })
            .catch(error => {
                console.error('Error:', error);
            });
    }

    // 加入房间 (会在login之后调用)
    function goRoom() {
        // 获取Query中的room_id
        var queryString = window.location.search;
        var params = new URLSearchParams(queryString);

        var roomId = params.get('room_id');
        if (roomId == null) {
            // 没有邀请
            return;
        }

        // 如果当前玩家已经在房间中，则不需要再次加入
        if (roomId === ROOM_ID) {
            return;
        }


        const url = getDomain() + '/api/join_room';

        var formData = new FormData();
        formData.append("token", TOKEN);
        formData.append("room_id", roomId);

        fetch(url, {
            method: 'POST',
            body: formData
        })
            .then(response => response.json())
            .then(data => {
                if (data.code != 0) {
                    alert("成功加入房间");
                    ROOM_ID = roomId

                    // 如果是加入房间的人，则隐藏创建房间的按钮
                    document.getElementById("CreateRoom").style.display = "none";
                    document.getElementById("start_game").style.display = "none";

                }
                console.log('Response:', data);
            })
            .catch(error => {
                console.error('Error:', error);
            });
    }

    // 开始游戏
    function start_game() {
        // 判断是否可以开始游戏
        if (ROOM_ID === "" || TOKEN === "" || WS == null) {
            alert("当前状态不允许开始游戏");
            return;
        }

        if (ROOM_USER_COUNT < 2) {
            alert("人数不足，无法开始游戏");
            return;
        }

        const url = getDomain() + '/api/start_game';

        var formData = new FormData();
        formData.append("room_id", ROOM_ID);

        fetch(url, {
            method: 'POST',
            body: formData
        })
            .then(response => response.json())
            .then(data => {
                if (data.code != 0) {
                    console.log("开始游戏");
                }
                console.log('Response:', data);
            })
            .catch(error => {
                console.error('Error:', error);
            });


    }

    // 有用户加入房间执行代码
    // function join_room(user_id) {
    //     getRoomInfo();
    // // 复制BoardRaw的内容添加到competitor_area中
    // var BoardRaw = document.getElementById("BoardRaw");
    //
    // var competitor_area = document.getElementById("competitor_area");
    //
    //
    // // 创建一个td
    // var td = document.createElement("td");
    //
    // var new_id = "competitor_area_" + user_id;
    // td.setAttribute("id", new_id);
    // td.setAttribute("style", "width: 100%;");
    //
    // // 复制BoardRaw的内容添加到td中
    // td.innerHTML = BoardRaw.innerHTML;
    //
    // // 将td加入到competitor_area中
    // competitor_area.appendChild(td);
    //
    // // 设置对手的名字
    // var competitor_name = document.getElementById(new_id);
    // competitor_name.getElementsByClassName("user_name")[0].innerHTML = "对手ID:" + user_id;
    // }

    // 获取游戏棋盘数据
    function get_game_data() {
        const url = getDomain() + '/api/get_game_board';

        var formData = new FormData();
        formData.append("room_id", ROOM_ID);
        formData.append("index", GAME_INDEX);

        fetch(url, {
            method: 'POST',
            body: formData
        })
            .then(response => response.json())
            .then(data => {
                if (data.code != 0) {
                    console.log(data.data.randArr)
                    GAME_RANDOM = data.data.randArr;
                }
                console.log('Response:', data);
            })
            .catch(error => {
                console.error('Error:', error);
            });
    }

    // 将自己的游戏界面同步到服务器
    function syncGame() {
        // 获取游戏的棋盘数据
        var board = getBoard();

        var data = {
            "board": board,
            "room_id": ROOM_ID,
            "token": TOKEN,
            "score": score,
            "game_status": USER_GAME_STATUS,
            "index": GAME_INDEX
        }

        const url = getDomain() + '/api/sync_game';

        fetch(url, {
            method: 'POST',
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(data)
        })
            .then(response => response.json())
            .then(data => {
                console.log('Response:', data);
            })
            .catch(error => {
                console.error('Error:', error);
            });

    }


    // 获取房间信息
    function getRoomInfo() {
        // 判断当前状态，是否可以创建房间
        if (TOKEN === "" || WS == null) {
            alert("当前状态不正常");
            return;
        }

        const url = getDomain() + '/api/get_room_info';
        const data = {
            token: TOKEN
        };

        fetch(url, {
            method: 'GET',
            headers: {},
            query: data
        })
            .then(response => response.json())
            .then(data => {
                if (data.code == 0) {
                    alert(data.msg);
                    return;
                }

                GAME_RANDOM = data.data.rand_arr;
                ROOM_OWNER = data.data.owner;
                GAME_TIMEOUT = data.data.timeout;
                GAME_STATUS = data.data.game_status;
                setGameStatus(data.data.game_status)

                if (GAME_STATUS == 1) {
                    beginGame();
                }

                // 构建对手的界面
                reBuildCompetitorBar(data.data.user_list);

            })
            .catch(error => {
                console.error('Error:', error);
            });
    }

</script>


<script>
    var BX = new Array(4);
    var BY = new Array(4);
    var PX = new Array(4);
    var PY = new Array(4);
    var mTimer
    var firstView

    var score = 0;

    var sTimer;

    // 开始游戏
    function beginGame() {
        startTimer();
        console.log("开始游戏");

        // 速度
        speed = Math.floor(score / 3000) + 1;
        outTime = 1100 - speed * 100;

        if (GAME_STATUS != 1) {
            return;
        }

        if (USER_GAME_STATUS != 1) {
            return;
        }

        // if (!searchBX()) {
        //     randBar();
        // }
        searchBX();
        moveBar();

        window.clearInterval(mTimer);
        mTimer = window.setInterval("moveBar()", outTime);
    }

    function searchBX() {
        let bxi = 0;
        let flag = false;
        // 高度为16
        for (j = 0; j < 16; j++)
            // 宽度为10
            for (i = 0; i < 10; i++)
                if (getClass(i, j,) == "MB") {
                    BX[bxi] = i;
                    BY[bxi] = j;
                    bxi++;
                    flag = true;
                }


        return flag;
    }

    // 开始游戏，清除方块
    function beginGameClear() {
        // 高度为16
        for (j = 0; j < 16; j++)
            // 宽度为10
            for (i = 0; i < 10; i++)
                setClass(i, j, "BK");
    }


    // 游戏结束计时器
    function startTimer() {
        sTimer = window.setInterval(function () {
            syncGame();
            // // 判断是否已经到结束游戏时间
            // var curr_time = new Date().getTime();
            //
            // if (curr_time >= GAME_END_TIME) {
            //     window.clearInterval(sTimer);
            // }

        }, 200);
    }


    // 获取整个棋盘的数据
    function getBoard() {
        var board = new Array(16);
        for (j = 0; j < 16; j++) {
            board[j] = new Array(10);
            for (i = 0; i < 10; i++) {
                board[j][i] = getClass(i, j);
            }
        }
        return board;
    }


    // 控制键
    function keyControl() {
        if (USER_GAME_STATUS != 1) return;
        switch (event.keyCode) {
            case 37: {    //left
                // 如果到了最左边
                for (i = 0; i < 4; i++) if (BX[i] == 0) return;
                // 如果左边有方块
                for (i = 0; i < 4; i++) if (getClass(BX[i] - 1, BY[i]) == "SB") return;
                // 左移一个位置
                for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "BK");
                for (i = 0; i < 4; i++) BX[i] = BX[i] - 1;
                for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "MB");
                break;
            }
            // 转换形状
            case 38: {    //up
                var preMBarX = new Array(4);
                var preMBarY = new Array(4);
                var cx = Math.round((BX[0] + BX[1] + BX[2] + BX[3]) / 4);
                var cy = Math.round((BY[0] + BY[1] + BY[2] + BY[3]) / 4);
                for (i = 0; i < 4; i++) {
                    /*
                    这个地方有必要做一下笔记，下面给出的计算方法是最终优化过的答案，所以不容易看出来
                    需要考虑的第一个问题是，将方块逆时针旋转90度之后，它的x y坐标分别是多少
                    这是围着原点在旋转(cx,xy)
                    我们试想在这个坐标系上面，有一个点，它的坐标是 2,3
                    把它逆时针旋转90度 (旋转后的结果是 -3,2)
                    也就是把整个坐标系逆时针旋转了90度
                    那么，结论就是。
                    正x 会变成 正y
                    负x 会变成 负y
                    正y 会变成 负x
                    负y 会变成 正x
                    -------
                    x变y的时候，直接变
                    y变x的时候，加个负
                    也就是说
                    新x = 旧负y
                    新y = 旧x

                    旋转问题我们解决了，再来解决x和y到底是多少的问题
                    因为(cx,cy)是圆点，所以x和y的距离，分别就是当前方块的x和y到 cx cy的距离
                    方块的x和y分别表示方式为BX[i] BY[i]   (i是第几个方块)
                    所以
                    x = -(cy-BY[i])
                    y = (cx-BX[i])

                    这好像就是答案了？并不是
                    x和y只是以cx,cy为原点来算的。我们真正的坐标系的原点在左上角。所以，还要把cx cy的距离加回来
                    x = cx - (cy-BY[i])
                    y = cy + (cx-BX[i])
                    再把这个试子简化一点
                    x = cx-(cy-BY[i])
                    y = cy+cx-BX[i]
                    这样就完美了

                    -----
                    再来
                    如果是顺时针啦？
                    新x = 旧y
                    新y = 旧负x
                    x = cx + (cy-BY[i])
                    y = cy - (cx-BX[i])

                     */
                    // 逆时针
                    preMBarX[i] = Math.round(cx - (cy - BY[i]));
                    preMBarY[i] = Math.round(cy + cx - BX[i]);

                    // 顺时针
                    // preMBarX[i] = Math.round(cx+(cy-BY[i]));
                    // preMBarY[i] = Math.round(cy-(cx-BX[i]));


                    // 原文的
                    // preMBarX[i] = Math.round(cx - cy + BY[i]);
                    // preMBarY[i] = Math.round(cx + cy - BX[i]);
                    if (preMBarX[i] < 0 || preMBarX[i] > 9 || preMBarY[i] < 0 || preMBarY[i] > 15) return;
                    if (getClass(preMBarX[i], preMBarY[i]) == "SB") return;
                }
                for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "BK");
                for (i = 0; i < 4; i++) {
                    BX[i] = preMBarX[i];
                    BY[i] = preMBarY[i];
                }
                for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "MB");
                break;
            }
            case 39: {    //right
                for (i = 0; i < 4; i++) if (BX[i] == 9) return;
                for (i = 0; i < 4; i++) if (getClass(BX[i] + 1, BY[i]) == "SB") return;
                for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "BK");
                for (i = 0; i < 4; i++) BX[i] = BX[i] + 1;
                for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "MB");
                break;
            }
            case 40: {    //down
                moveBar();
                break;
            }
        }
    }

    // 检测是否有组成一条线
    // 在不能下降时，会调用这里
    function delLine() {
        // 把方块改成砖块颜色
        for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "SB");

        // 找是否组成一条线
        for (j = 0; j < 16; j++) {
            dLine = true;
            for (i = 0; i < 10; i++) {
                if (getClass(i, j) != "SB") {
                    dLine = false;
                    break;
                }
            }
            // 组成一条线了
            if (dLine) {
                // 积分 + 100
                score = score + 100;

                // 从找到这条线的地方，以上的方块，都要下层一个位置
                for (k = j; k > 0; k--)
                    for (l = 0; l < 10; l++)
                        setClass(l, k, getClass(l, k - 1));
                // 填充一行白色
                for (l = 0; l < 10; l++) setClass(l, 0, "BK");
            }
        }
        BX = new Array(4)
        BY = new Array(4)
        moveBar()

        // 加积分和调速度
        speed = Math.floor(score / 3000) + 1;
        outTime = 1100 - speed * 100;
        scoreBar.innerHTML = "Score : " + score;
        speedBar.innerHTML = "Speed : " + speed;
        window.clearInterval(mTimer);
        mTimer = window.setInterval("moveBar()", outTime);
    }

    function getClass(x, y) {
        return GameBar.children[y].children[x].className;
    }

    function setClass(x, y, cName) {
        GameBar.children[y].children[x].className = cName;
    }

    function setClass2(bar, x, y, cName) {
        bar.children[y].children[x].className = cName;
    }

    // 把准备区的方块放到游戏区来，然后在准备区生成一个方块
    function randBar() {
        // 随机数
        // randNum = Math.floor(Math.random() * 20) + 1;
        var randNum = GAME_RANDOM[GAME_INDEX];
        GAME_INDEX++;

        // 如果准备见底，就需要获取新的数据
        if (GAME_RANDOM.length - GAME_INDEX < 20) {
            get_game_data();
        }
        firstView = true;
        // 如果预备区有值
        if (PX[0] != undefined) {
            firstView = false;
            for (i = 0; i < 4; i++) {
                BX[i] = PX[i];
                BY[i] = PY[i];
            }
        }


        // 所有图形都是由四个点组成的，所以只需要标明四个点即可  0-3
        // value 就是x y的位置
        // 但是 为什么x要从4开始就不知道了，因为最后它减了3来显示位置。下面的注释有给出答案
        switch (randNum) {
            case 1: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 1;
                PX[3] = 6;
                PY[3] = 1;
                break;
            }
            case 2: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 4;
                PY[3] = 2;
                break;
            }
            case 3: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 6;
                PY[2] = 0;
                PX[3] = 6;
                PY[3] = 1;
                break;
            }
            case 4: {
                PX[0] = 5;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 2;
                PX[3] = 4;
                PY[3] = 2;
                break;
            }
            case 5: {
                PX[0] = 6;
                PY[0] = 0;
                PX[1] = 6;
                PY[1] = 1;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 5;
                PY[3] = 1;
                break;
            }
            case 6: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 1;
                PX[2] = 4;
                PY[2] = 2;
                PX[3] = 5;
                PY[3] = 2;
                break;
            }
            case 7: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 0;
                PX[3] = 6;
                PY[3] = 0;
                break;
            }
            case 8: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 5;
                PY[2] = 1;
                PX[3] = 5;
                PY[3] = 2;
                break;
            }
            case 9: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 5;
                PY[2] = 1;
                PX[3] = 6;
                PY[3] = 1;
                break;
            }
            case 10: {
                PX[0] = 5;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 4;
                PY[3] = 2;
                break;
            }
            case 11: {
                PX[0] = 4;
                PY[0] = 1;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 0;
                PX[3] = 6;
                PY[3] = 0;
                break;
            }
            case 12: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 1;
                PX[3] = 5;
                PY[3] = 2;
                break;
            }
            case 13: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 6;
                PY[2] = 0;
                PX[3] = 5;
                PY[3] = 1;
                break;
            }
            case 14: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 1;
                PX[2] = 4;
                PY[2] = 2;
                PX[3] = 5;
                PY[3] = 1;
                break;
            }
            case 15: {
                PX[0] = 5;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 6;
                PY[3] = 1;
                break;
            }
            case 16: {
                PX[0] = 5;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 2;
                PX[3] = 4;
                PY[3] = 1;
                break;
            }
            case 17: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 5;
                PY[3] = 1;
                break;
            }
            case 18: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 5;
                PY[3] = 1;
                break;
            }
            case 19: {
                PX[0] = 3;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 0;
                PX[2] = 5;
                PY[2] = 0;
                PX[3] = 6;
                PY[3] = 0;
                break;
            }
            case 20: {
                PX[0] = 5;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 2;
                PX[3] = 5;
                PY[3] = 3;
                break;
            }
        }
        if (firstView) {
            firstView = false;
            randBar();
            return;
        }
        // 预览区空白
        for (i = 0; i < 4; i++) {
            for (j = 0; j < 4; j++) {
                previewBar.children[j].children[i].className = "BK";
            }
        }

        // 这里的x为什么要减3，不知道，但是上面的设置是+3的基础之上的
        // 这里为什么要+3的基础，是因为游戏区的宽度是10，然而方块占用的宽度是4  所以 3+4+3=10 所以+3 方块开始的时候，就刚好在中间位置
        for (i = 0; i < 4; i++)
            previewBar.children[PY[i]].children[PX[i] - 3].className = "MB";

        // 方块开始出来的区域，如果不是白色的话，说明已经被其他方块占用了，则游戏结束
        for (i = 0; i < 4; i++) {
            if (getClass(BX[i], BY[i]) != "BK") {
                gameOver();
                return;
            }
        }
        // 设置方块的颜色
        for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "MB");
    }


    // 预览区方块
    function previewBarSet() {
        // 如果预览区没有方块，就创建一个
        if (PX[0] || PX[1] || PX[2] || PX[3]) {
            // 证明预览区有方块
            return;
        }

        // 创建一个方块
        var randNum = GAME_RANDOM[GAME_INDEX];
        GAME_INDEX++;

        // 如果准备见底，就需要获取新的数据
        if (GAME_RANDOM.length - GAME_INDEX < 20) {
            get_game_data();
        }

        // 所有图形都是由四个点组成的，所以只需要标明四个点即可  0-3
        // value 就是x y的位置
        // 但是 为什么x要从4开始就不知道了，因为最后它减了3来显示位置。下面的注释有给出答案
        switch (randNum) {
            case 1: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 1;
                PX[3] = 6;
                PY[3] = 1;
                break;
            }
            case 2: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 4;
                PY[3] = 2;
                break;
            }
            case 3: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 6;
                PY[2] = 0;
                PX[3] = 6;
                PY[3] = 1;
                break;
            }
            case 4: {
                PX[0] = 5;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 2;
                PX[3] = 4;
                PY[3] = 2;
                break;
            }
            case 5: {
                PX[0] = 6;
                PY[0] = 0;
                PX[1] = 6;
                PY[1] = 1;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 5;
                PY[3] = 1;
                break;
            }
            case 6: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 1;
                PX[2] = 4;
                PY[2] = 2;
                PX[3] = 5;
                PY[3] = 2;
                break;
            }
            case 7: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 0;
                PX[3] = 6;
                PY[3] = 0;
                break;
            }
            case 8: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 5;
                PY[2] = 1;
                PX[3] = 5;
                PY[3] = 2;
                break;
            }
            case 9: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 5;
                PY[2] = 1;
                PX[3] = 6;
                PY[3] = 1;
                break;
            }
            case 10: {
                PX[0] = 5;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 4;
                PY[3] = 2;
                break;
            }
            case 11: {
                PX[0] = 4;
                PY[0] = 1;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 0;
                PX[3] = 6;
                PY[3] = 0;
                break;
            }
            case 12: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 1;
                PX[3] = 5;
                PY[3] = 2;
                break;
            }
            case 13: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 6;
                PY[2] = 0;
                PX[3] = 5;
                PY[3] = 1;
                break;
            }
            case 14: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 1;
                PX[2] = 4;
                PY[2] = 2;
                PX[3] = 5;
                PY[3] = 1;
                break;
            }
            case 15: {
                PX[0] = 5;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 6;
                PY[3] = 1;
                break;
            }
            case 16: {
                PX[0] = 5;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 2;
                PX[3] = 4;
                PY[3] = 1;
                break;
            }
            case 17: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 5;
                PY[3] = 1;
                break;
            }
            case 18: {
                PX[0] = 4;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 0;
                PX[2] = 4;
                PY[2] = 1;
                PX[3] = 5;
                PY[3] = 1;
                break;
            }
            case 19: {
                PX[0] = 3;
                PY[0] = 0;
                PX[1] = 4;
                PY[1] = 0;
                PX[2] = 5;
                PY[2] = 0;
                PX[3] = 6;
                PY[3] = 0;
                break;
            }
            case 20: {
                PX[0] = 5;
                PY[0] = 0;
                PX[1] = 5;
                PY[1] = 1;
                PX[2] = 5;
                PY[2] = 2;
                PX[3] = 5;
                PY[3] = 3;
                break;
            }
        }

        // 预览区空白
        for (i = 0; i < 4; i++) {
            for (j = 0; j < 4; j++) {
                previewBar.children[j].children[i].className = "BK";
            }
        }

        // 这里的x为什么要减3，不知道，但是上面的设置是+3的基础之上的
        // 这里为什么要+3的基础，是因为游戏区的宽度是10，然而方块占用的宽度是4  所以 3+4+3=10 所以+3 方块开始的时候，就刚好在中间位置
        for (i = 0; i < 4; i++)
            previewBar.children[PY[i]].children[PX[i] - 3].className = "MB";

    }

    // 游戏区
    function gameBarSet() {
        // 证明游戏区有方块
        if (BX[0] || BX[1] || BX[2] || BX[3]) {
            return;
        }

        // 判断是否有足够的位置放下新的方块
        // 方块开始出来的区域，如果不是白色的话，说明已经被其他方块占用了，则游戏结束
        for (i = 0; i < 4; i++) {
            if (getClass(PX[i], PY[i]) != "BK") {
                gameOver();
                return;
            }
        }

        // 从预览区复制一个方块
        for (i = 0; i < 4; i++) {
            BX[i] = PX[i];
            BY[i] = PY[i];
        }

        // 设置方块的颜色
        for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "MB");

        PX = new Array(4)
        PY = new Array(4)
        // 应该在预览区再创建一个
        previewBarSet();
    }


    // 方块定时移动
    function moveBar() {
        // 如果游戏不是开始状态，直接结束
        if (USER_GAME_STATUS != 1) return;
        syncGame();

        // 判断预览区是否有方块，如果没有就要创建一个
        previewBarSet();

        // 判断是否有方块正在下降，如果没有，就从预览区复制一个过来
        gameBarSet();

        // 在这里可能游戏已经结束
        if (USER_GAME_STATUS != 1) return;

        // 是否可以继续下降
        dropLine = true;
        // 如果已经到了最底下就不能再下降了
        for (i = 0; i < 4; i++)
            if (BY[i] == 15)
                dropLine = false;


        if (dropLine)
            // 如果下一个位置有方块的颜色了，也不能下降了
            for (i = 0; i < 4; i++)
                if (getClass(BX[i], BY[i] + 1) == "SB")
                    dropLine = false;

        // 如果不能下降了
        if (!dropLine) {
            // 停止计时器
            // window.clearInterval(mTimer);

            delLine();
            return;
        }
        // 下降一个位置 MB是红色，在下降的时候，还是红色的
        for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "BK");
        for (i = 0; i < 4; i++) BY[i] = BY[i] + 1;
        for (i = 0; i < 4; i++) setClass(BX[i], BY[i], "MB");
    }


    function fMnu() {
        return false;
    }

    document.oncontextmenu = fMnu;


    // 游戏结束
    function gameOver() {
        window.clearInterval(mTimer);
        window.clearInterval(sTimer);

        USER_GAME_STATUS = 2;
        syncGame();

        console.log("Game Over!");
    }
</script>